package org.aplikator.client.shared.rpc.marshaller;

import org.aplikator.client.shared.data.ListItem;
import org.aplikator.client.shared.rpc.marshaller.DataMarshallingUtils.DataType;
import org.jboss.errai.marshalling.client.api.MarshallingSession;
import org.jboss.errai.marshalling.client.api.annotations.ClientMarshaller;
import org.jboss.errai.marshalling.client.api.annotations.ImplementationAliases;
import org.jboss.errai.marshalling.client.api.annotations.ServerMarshaller;
import org.jboss.errai.marshalling.client.api.json.EJObject;
import org.jboss.errai.marshalling.client.api.json.EJValue;
import org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller;

import java.io.Serializable;

@ClientMarshaller(ListItem.class)
@ServerMarshaller(ListItem.class)
@ImplementationAliases({ListItem.Default.class})
public class ListItemMarshaller extends AbstractNullableMarshaller<ListItem> {

	/*@Override
	public Class<ListItem> getTypeHandled() {
		return ListItem.class;
	}*/

	@Override
	public ListItem[] getEmptyArray() {
		return new ListItem[0];
	}

	@Override
	public ListItem doNotNullDemarshall(EJValue o, MarshallingSession ctx) {
		if (o.isObject() != null) {
			EJObject ejObject = o.isObject();
			String name = ejObject.get("name").isString().stringValue();
			if (ejObject.containsKey("value")) {
				DataType dt = DataMarshallingUtils.DataType.lookup(ejObject.get("value"));
				if (dt != null) {
					Serializable serialized = dt.demarshall(ejObject.get("value"), ctx);
					return new ListItem.Default(serialized, name);
				} else throw new UnsupportedOperationException("unsupported type '"+dt+"'");
			} else throw new IllegalStateException("expect value key ");
		} else return null;
	}

	@Override
	public String doNotNullMarshall(ListItem o, MarshallingSession ctx) {
		StringBuilder builder = new StringBuilder().append('{');
		MarshallingUtils.string("name", o.getName(), builder);
		DataType dt = DataMarshallingUtils.DataType.lookup(o.getValue());
		if (dt != null) {
			builder.append(',');
			MarshallingUtils.key("value", builder).append(':');
			dt.marshall(builder, o.getValue(), ctx);
		} else throw new UnsupportedOperationException("unsupported type '"+dt+"'");
		builder.append('}');
		return builder.toString();
	}
}
